<script lang="ts" setup>
import {reactive, ref, computed, onMounted, watch} from 'vue'
import axios from "axios"

// #########################################
// 1.ref与reactive
const msg = ref('Hello, World!!')
const user2 = ref({name: 'xhai'})
const user1 = reactive({name: 'admin'})

function showUser2() {
  // reactive 包装的数据，在模板中和代码中都是一致的
  console.log(user1.name)
  // 在代码中要使用 ref 包装的数据，必须用【变量名.value】才能访问到
  console.log(user2.value.name)
}

showUser2()
// #########################################
// 2.属性绑定
const path = ref('/src/assets/vue.svg')

function changePath() {
  if (path.value === '/src/assets/vue.svg') {
    path.value = '/public/vite.svg'
  } else if (path.value === '/public/vite.svg') {
    path.value = '/src/assets/vue.svg'
  }
}

// #########################################
// 3.事件绑定
const count = ref(0)

function dec() {
  count.value--
}

function inc() {
  count.value++
}

// #########################################
// 4.表单绑定
const tableUser = ref({
  name: '张三',
  age: 18,
  sex: '男',
  fav: ['游泳', '打球']
})

function saveTableUser() {
  console.log(tableUser.value)
}

// #########################################
// 5.计算属性
const firstName = ref('三')
const lastName = ref('张')
const fullName = computed(() => {
  console.log('enter')
  return lastName.value + firstName.value
})

function funcFullName() {
  console.log('enter')
  return lastName.value + firstName.value
}

// #########################################
// 7.axios
let userList = ref([{}]);

async function getUsers() {
  try {
    const resp = await axios.post("/xh/sys/api/sysUser/page", {});
    userList.value = resp.data;
  } catch (e) {
    console.log(e);
  }
}

// onMounted 指 vue 组件生成的 html 代码片段，挂载完毕后被执行
onMounted(() => {
  getUsers()
})
// #########################################
// 8.条件与列表
let dataList = ref([{
  'id': 'id',
  'name': 'name',
  'sex': 'sex',
  'age': 'age'
}])
// #########################################
// 9.监听器
// 名称为 useXXXX 的函数，作用是返回带扩展功能的【响应式】数据
function useStorage(name: string) {
  // localStorage   即使浏览器关闭，数据还在
  // sessionStorage  数据工作在浏览器活动期间
  const data = ref(sessionStorage.getItem(name) ?? "");
  watch(data, (newValue) => {
    sessionStorage.setItem(name, newValue);
  });
  return data;
}

const name = useStorage("name");
</script>
<template>
  <!--  #########################################-->
  <!--  1.ref与reactive-->
  <!--  ref 能将任意类型的数据变为【响应式】的-->
  <h1>{{ msg }}</h1>
  <!--  reactive 只能将对象类型变为【响应式】，对基本类型无效（例如 string，number，boolean）-->
  <!--  reactive 包装的数据，在模板中和代码中都是一致的-->
  <h2>{{ user1.name }}</h2>
  <!--  在 template 模板中使用 ref 包装的数据，直接写【变量名】就可以了-->
  <h2>{{ user2.name }}</h2>
  <br/>

  <!--  #########################################-->
  <!--  2.属性绑定-->
  <!--  【:属性名】用来将标签属性与【响应式】变量绑定-->
  <img :src="path" alt="">
  <input type="button" value="修改图片path" @click="changePath"/>
  <br/>

  <!--  #########################################-->
  <!--  3.事件绑定-->
  <!--  【@事件名】用来将标签属性与函数绑定，事件发生后执行函数内代码-->
  <input type="button" value="-" @click="dec">
  <h2>{{ count }}</h2>
  <input type="button" value="+" @click="inc">
  <br/>

  <!--  #########################################-->
  <!--  4.表单绑定-->
  <!--  用 v-model 实现双向绑定-->
  <!--    javascript 数据可以同步到表单标签-->
  <!--    反过来用户在表单标签输入的新值也会同步到 javascript 这边-->
  <!--  双向绑定只适用于表单这种带【输入】功能的标签，其它标签的数据绑定，单向就足够了-->
  <!--  复选框这种标签，双向绑定的 javascript 数据类型一般用数组-->
  <div class="outer">
    <div>
      <label for="">请输入姓名</label>
      <input v-model="tableUser.name" type="text"/>
    </div>
    <div>
      <label for="">请输入年龄</label>
      <input v-model="tableUser.age" type="text"/>
    </div>
    <div>
      <label for="">请选择性别</label>
      男 <input v-model="tableUser.sex" type="radio" value="男"/>
      女 <input v-model="tableUser.sex" type="radio" value="女"/>
    </div>
    <div>
      <label for="">请选择爱好</label>
      游泳 <input v-model="tableUser.fav" type="checkbox" value="游泳"/>
      打球 <input v-model="tableUser.fav" type="checkbox" value="打球"/>
      健身 <input v-model="tableUser.fav" type="checkbox" value="健身"/>
    </div>
    <div>
      <input type="button" value="保存" @click="saveTableUser">
    </div>
  </div>
  <br/>

  <!--  #########################################-->
  <!--  5.计算属性-->
  <!--  fullName 即为计算属性，它具备缓存功能，即 firstName 和 lastName 的值发生了变化，才会重新计算，并且只计算一次-->
  <!--  用函数实现相同功能，则没有缓存功能-->
  <h2>{{ fullName }}</h2>
  <h3>{{ fullName }}</h3>
  <h4>{{ funcFullName() }}</h4>
  <br/>

  <!--  #########################################-->
  <!--  7.axios-->
  <h2>用户信息为：{{ userList }}</h2>
  <br/>

  <!--  #########################################-->
  <!--  8.条件与列表-->
  <!--  v-if 与 v-else 不能和 v-for 处于同一标签-->
  <div v-if="dataList.length === 0">暂无数据</div>
  <template v-else>
    <div v-for="s of dataList" :key="s.id" class="row">
      <div class="col">{{ s.id }}</div>
      <div class="col">{{ s.name }}</div>
      <div class="col">{{ s.sex }}</div>
      <div class="col">{{ s.age }}</div>
    </div>
  </template>
  <br/>

  <!--  #########################################-->
  <!--  9.监听器-->
  <input v-model="name" type="text"/>
</template>

<style scoped>
div {
  margin-bottom: 8px;
}

.outer {
  width: 100%;
  position: relative;
  padding-left: 80px;
}

label {
  text-align: left;
  width: 100px;
  display: inline-block;
  position: absolute;
  left: 0;
}
</style>